﻿/**
 * SlotDuino
 * 
 * Copyright (c) 2011/2012 Thiago Hummel Moreira, Ricardo Mizuuti, Rafael Mufato, Bruno Sakai, Andre Turina
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
using System;
using System.Data;
using System.Data.Objects;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using SlotDuino.DAL;
using SlotDuino.Util;

namespace SlotDuino.UI.Pages
{
    /// <summary>
    /// Interaction logic for PilotManager.xaml
    /// </summary>
    public partial class PilotManager : Page
    {
        #region Dependency properties
        public static readonly DependencyProperty IsEditingProperty = DependencyProperty.Register("IsEditing", typeof(bool), typeof(PilotManager));
        public static readonly DependencyProperty CurrentInstanceProperty = DependencyProperty.Register("CurrentInstance", typeof(Pilot), typeof(PilotManager));
        #endregion

        #region Private attributes
        private EntityContainer _context;
        private CollectionViewSource _viewSource;
        private BindingListCollectionView _view;
        #endregion

        #region Public properties
        protected BindingListCollectionView View
        {
            get { return _view; }
        }

        public bool IsEditing
        {
            get { return (bool)GetValue(IsEditingProperty); }
            set { SetValue(IsEditingProperty, value); }
        }
        
        public Pilot CurrentInstance
        {
            get { return (Pilot)GetValue(CurrentInstanceProperty); }
            set { SetValue(CurrentInstanceProperty, value); }
        }
        #endregion

        public PilotManager()
        {
            InitializeComponent();
            IsEditing = false;
        }

        private IQueryable<Pilot> GetQuery(EntityContainer context, string search = null)
        {
            IQueryable<Pilot> query;
            if (null != search)
            {
                query = from p in context.People.OfType<Pilot>() where p.Name.Contains(search) || p.Nickname.Contains(search) select p;
            }
            else
            {
                query = from p in context.People.OfType<Pilot>() select p;
            }

            return query;
        }

        private void RefreshData(string search = null)
        {
            //Refresh Data
            _viewSource.Source = GetQuery(_context, search);
            _view = (BindingListCollectionView)_viewSource.View;
        }

        private void StartEdit(Pilot instance)
        {
            if (EntityState.Detached == instance.EntityState)
            {
                _context.AddToPeople(instance);
            }
            
            CurrentInstance = instance;
            IsEditing = true;
            txtName.Focus();
        }

        private void EndEdit()
        {
            IsEditing = false;
            CurrentInstance = null;
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            //Create the entity context
            _context = new EntityContainer();
            //Get a reference to viewSource (defined on the XAML)
            _viewSource = ((CollectionViewSource)(FindResource("viewSource")));

            RefreshData();
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            RefreshData(txtSearch.Text);
        }
        
        private void btnNew_Click(object sender, RoutedEventArgs e)
        {
            dataGrid.SelectedItem = null;
            StartEdit(new Pilot());
        }

        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            StartEdit((Pilot)dataGrid.SelectedItem);
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //This must come before the saveChanges, or else we will not know 
                string msg = String.Format("Piloto '{0}' {1} com sucesso.", 
                    CurrentInstance.Name,
                    (EntityState.Added == CurrentInstance.EntityState ? "adicionado" : "atualizado")
                );

                _context.SaveChanges();

                Msg.ShowOk(msg);
                
                EndEdit();

                RefreshData(txtSearch.Text);
            }
            catch (Exception ex)
            {
                Msg.ShowError(ex.Message);
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            if (EntityState.Added != CurrentInstance.EntityState)
            {
                _context.Refresh(RefreshMode.StoreWins, CurrentInstance);
            }
            else
            {
                _context.DeleteObject(CurrentInstance);
            }
            
            EndEdit();
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (null == CurrentInstance && null != dataGrid.SelectedItem)
            {
                StartEdit((Pilot)dataGrid.SelectedItem);
            }
            else
            {
                //The button should be disabled in these cases
                return;
            }

            string name = CurrentInstance.Name; //Store it to use after exclusion

            if (Msg.ShowConfirm(String.Format("Deseja excluir o piloto '{0}'?", name)) == MessageBoxResult.Yes)
            {
                try
                {
                    //Check for races
                    if (0 < CurrentInstance.RacesSlots.Count)
                    {
                        throw new Exception(String.Format("O piloto '{0}' não pode ser removido pois esta vinculado a {1} corrida(s)!",
                            name, CurrentInstance.RacesSlots.Count));
                    }

                    //Check for championships enrollments
                    if (0 < CurrentInstance.ChampionshipEnrollments.Count)
                    {
                        throw new Exception(String.Format("O piloto '{0}' não pode ser removido pois esta vinculado a {1} campeonato(s)!",
                            name, CurrentInstance.ChampionshipEnrollments.Count));
                    }

                    _context.DeleteObject(CurrentInstance);
                    _context.SaveChanges();

                    Msg.ShowOk(String.Format("Piloto '{0}' excluído com sucesso.", name));
                }
                catch (Exception ex)
                {
                    Msg.ShowError(ex.Message);
                }
                finally
                {
                    RefreshData(txtSearch.Text);
                }

                EndEdit();
            }
        }
    }
}
